<template>
  <div class="chat-container">
    <!-- 会话控制 -->
    <div class="ai-header">
      <el-alert
        title="AI 古籍智能助手"
        type="info"
        :closable="false"
        description="您可以询问关于古籍的任何问题"
      />
    </div>

    <!-- 消息列表 -->
    <div class="messages" ref="messagesContainer">
      <div v-for="(message, index) in messages" :key="index" :class="['message', message.role]">
        <div class="message-role">{{ message.role === "user" ? "你" : "AI" }}</div>
        <div class="message-content" v-html="message.content"></div>
        <div class="message-time">
          {{ formatDateTime(message.createTime || new Date()) }}
        </div>
      </div>
      <div v-if="isLoading" class="loading-indicator">
        <div class="typing-animation">
          <span></span>
          <span></span>
          <span></span>
        </div>
      </div>
    </div>

    <!-- 输入区域 -->

    <div class="input-area">
      <el-input
        v-model="userInput"
        placeholder="输入您的问题..."
        type="textarea"
        :rows="4"
        :disabled="isLoading"
      />
      <el-button
        type="primary"
        @click="sendMessage"
        class="send-btn"
        :disabled="!userInput.trim() || isLoading"
      >
        <span v-if="!isLoading">发送</span>
        <span v-else>发送中...</span>
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "Chat",
  inheritAttrs: false,
});

const props = defineProps({
  articleId: {
    type: Number,
    default: null,
    required: true,
  },
});

import { ref, onMounted, nextTick, watch } from "vue";
import ChatAPI, { type ChatMessageVO, type ChatRequest } from "@/api/project/chat";

// 数据状态
const sessionId = ref("");
const messages = ref<ChatMessageVO[]>([]);
const userInput = ref("");
const isLoading = ref(false);
const messagesContainer = ref<HTMLElement | null>(null);
const abortController = ref<AbortController | null>(null);

// 加载历史消息
const loadHistory = async () => {
  if (!props.articleId) return;
  try {
    const res = await ChatAPI.getArticleHistory(props.articleId);
    messages.value = res;
    scrollToBottom();
  } catch (error) {
    console.error("加载历史失败:", error);
  }
};

// 使用 watch 监听 props.articleId 的变化
watch(
  () => props.articleId,
  (newVal) => {
    if (newVal !== undefined && newVal !== null) {
      loadHistory();
    }
  },
  { immediate: true }
);

// 发送消息
const sendMessage = async () => {
  const content = userInput.value.trim();
  if (!content || !props.articleId || isLoading.value) return;

  // 中止之前的请求
  abortController.value?.abort();
  abortController.value = new AbortController();

  // 添加用户消息
  addMessage({
    id: "0",
    role: "user",
    content,
    articleId: props.articleId,
  });

  userInput.value = "";
  isLoading.value = true;

  // 添加AI消息占位
  const aiMessage = addMessage({
    id: "0",
    role: "assistant",
    content: "",
    articleId: props.articleId,
  });

  try {
    await ChatAPI.streamMessage(
      {
        articleId: props.articleId,
        message: content,
      },
      (rawChunk) => {
        const regex = /"([^"]*)"/g;
        const matches = [];
        let match;
        while ((match = regex.exec(rawChunk)) !== null) {
          matches.push(match[1]);
        }

        const contentPart = matches.join("");
        const cleanedText = contentPart.replace(/\ndata:/g, "\n").replace(/\\ndata:/g, "\n");

        if (cleanedText) {
          const lastIndex = messages.value.length - 1;
          messages.value[lastIndex].content += cleanedText;
          scrollToBottom();
        }
      },
      (error) => {
        console.error("流式请求出错:", error);
        const lastIndex = messages.value.length - 1;
        messages.value[lastIndex].content += "\n[对话中断]";
        isLoading.value = false; // Add this line
      },
      abortController.value.signal
    );
  } catch (error) {
    console.error("发送消息失败:", error);
    const lastIndex = messages.value.length - 1;
    messages.value[lastIndex].content += "\n[请求失败]";
  } finally {
    isLoading.value = false;
    abortController.value = null;
  }
};

// 解析函数
const parseDataChunks = (chunks: string[]) => {
  let buffer = "";
  let result = "";

  chunks.forEach((chunk) => {
    buffer += chunk;
    const lines = buffer.split("\n");
    buffer = lines.pop(); // 最后一行可能不完整，暂存到 buffer

    lines.forEach((line) => {
      if (line.startsWith("data:")) {
        const dataContent = line.replace("data:", "").replace(/^"|"$/g, "");
        if (dataContent) {
          result += dataContent;
        }
      }
    });
  });

  // 处理 buffer 中剩余可能完整的数据
  if (buffer.startsWith("data:")) {
    const dataContent = buffer.replace("data:", "").replace(/^"|"$/g, "");
    if (dataContent) {
      result += dataContent;
    }
  }

  return result;
};

// 添加新消息
const addMessage = (message: ChatMessageVO): ChatMessageVO => {
  const newMessage = {
    ...message,
    id: Date.now().toString(),
  };
  messages.value.push(newMessage);
  scrollToBottom();
  return newMessage;
};

// 滚动到底部
const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
  });
};

// 格式化时间
const formatTime = (date: Date) => {
  return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
};

// 日期格式化函数
const formatDateTime = (date: Date | string) => {
  const dateObj = typeof date === "string" ? new Date(date) : date;
  const year = dateObj.getFullYear();
  const month = String(dateObj.getMonth() + 1).padStart(2, "0");
  const day = String(dateObj.getDate()).padStart(2, "0");
  const hours = String(dateObj.getHours()).padStart(2, "0");
  const minutes = String(dateObj.getMinutes()).padStart(2, "0");
  const seconds = String(dateObj.getSeconds()).padStart(2, "0");

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

// 初始化组件
onMounted(() => {
  //
});

// 组件卸载时中止请求
onUnmounted(() => {
  abortController.value?.abort();
});
</script>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 88vh;
  max-width: 800px;
  margin: 0 auto;
  padding: 5px;
  background-color: #f5f5f5;
  border-radius: 8px;
}

.ai-header {
  padding: 15px;
  border-bottom: 1px solid #ebeef5;
}

.session-id {
  font-size: 0.8rem;
  color: #666;
}

.messages {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  margin-bottom: 15px;
  background-color: white;
  border-radius: 8px;
  scroll-behavior: smooth;
}

.message {
  margin-bottom: 15px;
  padding: 10px 15px;
  border-radius: 8px;
  max-width: 80%;
}

.message.user {
  background-color: #e3f2fd;
  margin-left: auto;
}

.message.assistant {
  background-color: #f0f0f0;
  margin-right: auto;
}

.message-role {
  font-weight: bold;
  font-size: 0.8rem;
  margin-bottom: 5px;
  color: #555;
}

.message-content {
  white-space: pre-wrap;
  word-break: break-word;
  will-change: contents;
  overflow-wrap: anywhere;
}

.message-time {
  font-size: 0.7rem;
  color: #999;
  text-align: right;
  margin-top: 5px;
}

.loading-indicator {
  display: flex;
  justify-content: center;
  padding: 10px;
}

.typing-animation {
  display: flex;
  align-items: center;
  height: 17px;
}

.typing-animation span {
  height: 8px;
  width: 8px;
  margin: 0 2px;
  background-color: #999;
  border-radius: 50%;
  display: inline-block;
  animation: typing 1s infinite ease-in-out;
}

.typing-animation span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-animation span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-5px);
  }
}

.input-area textarea {
  flex: 1;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  resize: none;
  font-family: inherit;
}

.send-btn {
  margin-top: 10px;
  width: 100%;
}
</style>
